const { app, BrowserWindow, ipcMain, dialog, shell } = require('electron');
const path = require('path');
const fs = require('fs');
const fsPromises = require('fs').promises;
const { exec: execCallback } = require('child_process');
const isDev = process.env.NODE_ENV === 'development';
const os = require('os');
const ejs = require('ejs');
const crypto = require('crypto');
const { promisify } = require('util');
// 导入Vue项目构建处理程序
const { registerVueBuilderHandlers } = require('./main/ipc/vueBuilderHandler');

// 将exec转为Promise版本
const exec = promisify(execCallback);

// HTML实体解码函数
function decodeHtmlEntities(text) {
  if (!text || typeof text !== 'string') {
    return text;
  }
  
  return text
    .replace(/&#(\d+);/g, function(match, dec) {
      return String.fromCharCode(dec);
    })
    .replace(/&#x([0-9a-f]+);/gi, function(match, hex) {
      return String.fromCharCode(parseInt(hex, 16));
    })
    .replace(/&quot;/g, '"')
    .replace(/&apos;/g, "'")
    .replace(/&amp;/g, '&')
    .replace(/&lt;/g, '<')
    .replace(/&gt;/g, '>')
    .replace(/&#34;/g, '"')
    .replace(/&#39;/g, "'");
}

// 增强版的HTML处理函数，专门处理script标签和JSON数据
function processHtml(html) {
  if (!html || typeof html !== 'string') {
    return html;
  }
  
  try {
    // 标记所有script标签位置
    const scriptTags = [];
    let startIndex = 0;
    const scriptRegex = /<script\b[^>]*>([\s\S]*?)<\/script>/gi;
    let match;
    
    while ((match = scriptRegex.exec(html)) !== null) {
      scriptTags.push({
        fullMatch: match[0],
        content: match[1],
        startIndex: match.index,
        endIndex: match.index + match[0].length
      });
    }
    
    // 如果没有找到script标签，直接返回处理后的HTML
    if (scriptTags.length === 0) {
      return sanitizeFontNames(decodeHtmlEntities(html));
    }
    
    // 分段处理HTML和script内容
    let result = '';
    let lastIndex = 0;
    
    for (const scriptTag of scriptTags) {
      // 处理script标签前的HTML
      if (scriptTag.startIndex > lastIndex) {
        const htmlSegment = html.substring(lastIndex, scriptTag.startIndex);
        result += sanitizeFontNames(decodeHtmlEntities(htmlSegment));
      }
      
      // 处理script标签
      const scriptOpenTag = html.substring(
        scriptTag.startIndex, 
        scriptTag.startIndex + scriptTag.fullMatch.indexOf('>') + 1
      );
      const scriptContent = scriptTag.content;
      
      // 检查脚本内容是否包含JSON.stringify
      if (scriptContent.includes('JSON.stringify')) {
        // 特殊处理包含JSON.stringify的部分
        let processedContent = scriptContent;
        // 匹配EJS表达式和JSON.stringify组合的模式
        const jsonPattern = /<%=\s*JSON\.stringify\([^)]+\)\s*%>/g;
        processedContent = processedContent.replace(jsonPattern, match => {
          // 不对这部分内容应用HTML实体解码，保持原始状态
          return match;
        });
        
        // 对其余部分应用正常的解码
        processedContent = decodeJavaScript(processedContent);
        result += scriptOpenTag + processedContent + '</script>';
      } else {
        // 对普通script内容使用更精确的解码（保留JavaScript语法）
        const decodedScript = decodeJavaScript(scriptContent);
        result += scriptOpenTag + decodedScript + '</script>';
      }
      
      lastIndex = scriptTag.endIndex;
    }
    
    // 处理最后一个script标签后的HTML
    if (lastIndex < html.length) {
      const htmlSegment = html.substring(lastIndex);
      result += sanitizeFontNames(decodeHtmlEntities(htmlSegment));
    }
    
    return result;
    
  } catch (error) {
    console.error('Error processing HTML:', error);
    // 出错时回退到基本处理
    return sanitizeFontNames(decodeHtmlEntities(html));
  }
}

// 专门用于处理JavaScript代码的解码函数
function decodeJavaScript(code) {
  if (!code || typeof code !== 'string') {
    return code;
  }
  
  // 谨慎处理，只替换明确的实体，避免破坏JavaScript语法
  return code
    .replace(/&#34;/g, '"')
    .replace(/&#39;/g, "'")
    .replace(/&quot;/g, '"')
    .replace(/&apos;/g, "'")
    .replace(/&amp;/g, '&')
    .replace(/&lt;/g, '<')
    .replace(/&gt;/g, '>');
}

// 处理CSS字体名称的工具函数
function sanitizeFontNames(css) {
  if (!css || typeof css !== 'string') {
    return css;
  }
  
  // 移除@charset声明，它可能导致内联样式问题
  let sanitized = css
    .replace(/@charset\s+["']UTF-8[""];?/gi, '')
    .replace(/@charset\s+["']utf-8[""];?/gi, '')
    .trim();
  
  // 修复所有font-family声明中未引用的字体名称
  const fontFamilyPattern = /font-family\s*:\s*([^;"}]*?)([^;"}]*)/gi;
  
  sanitized = sanitized.replace(fontFamilyPattern, function(match, p1, p2) {
    // 处理字体名称列表
    return 'font-family: ' + p1 + p2
      .split(',')
      .map(font => {
        font = font.trim();
        // 通用字体关键字列表
        const systemFonts = [
          'serif', 'sans-serif', 'monospace', 'cursive', 'fantasy', 
          'system-ui', 'ui-serif', 'ui-sans-serif', 'ui-monospace', 
          'ui-rounded', 'emoji', 'math', 'fangsong'
        ];
        
        // 如果不是通用字体关键字且没有引号，则添加引号
        if (font && 
            !font.startsWith('"') && 
            !font.startsWith("'") && 
            !systemFonts.includes(font.toLowerCase())) {
          return `"${font}"`;
        }
        return font;
      })
      .join(', ');
  });
  
  return sanitized;
}

function createWindow() {
  console.log('创建主窗口...');
  console.log('预加载脚本路径:', path.join(__dirname, 'preload.js'));
  
  const mainWindow = new BrowserWindow({
    width: 1000,
    height: 800,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js'),
      nodeIntegration: false, // 设置为false，确保与contextIsolation兼容
      contextIsolation: true,
      webSecurity: true
    }
  })

  console.log('窗口创建完成，webPreferences:', {
    preload: path.join(__dirname, 'preload.js'),
    nodeIntegration: false,
    contextIsolation: true,
    webSecurity: true
  });

  // 设置内容安全策略
  mainWindow.webContents.session.webRequest.onHeadersReceived((details, callback) => {
    callback({
      responseHeaders: {
        ...details.responseHeaders,
        'Content-Security-Policy': ["default-src 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline' https://unpkg.com; style-src 'self' 'unsafe-inline' https://unpkg.com; connect-src 'self' https://unpkg.com"]
      }
    })
  })

  // 加载 Vite 开发服务器地址或构建后的 index.html
  if (isDev) {
    // Vite 默认端口是 5173
    console.log('开发模式：加载 http://localhost:5173');
    mainWindow.loadURL('http://localhost:5173');
    // 打开开发工具
    mainWindow.webContents.openDevTools();
    
    // 监听控制台消息
    mainWindow.webContents.on('console-message', (e, level, message, line, sourceId) => {
      console.log(`[Renderer Console][${level}] ${message}`);
    });
  } else {
    console.log('生产模式：加载', path.join(__dirname, '../dist/index.html'));
    mainWindow.loadFile(path.join(__dirname, '../dist/index.html'));
  }

  // 在窗口关闭时取消引用窗口对象
  mainWindow.on('closed', function () {
    // 在此处取消引用窗口对象。
    // 如果应用支持多窗口，通常会将窗口存储在数组中，此时应从该数组中删除对应元素。
    // mainWindow = null; // 这是单窗口情况下的做法，但在现代JS中通常不需要手动置为null
  });
}

// Helper function to get template content (assuming templates are relative to __dirname)
function getTemplateContent(templateName) {
    const templatePath = path.join(__dirname, '../src/templates', templateName);
    try {
        return fs.readFileSync(templatePath, 'utf-8');
    } catch (error) {
        console.error(`Error reading template ${templateName}:`, error);
        throw new Error(`Could not read template ${templateName}`);
    }
}

// 专门用于解码JSON字符串中的HTML实体的函数
function decodeJSONEntities(jsonString) {
  if (!jsonString || typeof jsonString !== 'string') {
    return jsonString;
  }
  
  // 首先尝试检查是否已经是有效的JSON
  try {
    // 如果可以正常解析，则它没有被编码为HTML实体
    JSON.parse(jsonString);
    return jsonString;
  } catch (e) {
    // 如果不能解析，可能是因为它包含了HTML实体
    console.log('JSON字符串可能包含HTML实体，尝试解码...');
    
    // 解码常见的HTML实体
    const decoded = jsonString
      .replace(/&quot;/g, '"')
      .replace(/&#34;/g, '"')
      .replace(/&apos;/g, "'")
      .replace(/&#39;/g, "'")
      .replace(/&amp;/g, '&')
      .replace(/&lt;/g, '<')
      .replace(/&gt;/g, '>');
    
    // 检查解码后是否为有效的JSON
    try {
      JSON.parse(decoded);
      console.log('JSON字符串解码成功');
      return decoded;
    } catch (decodeError) {
      console.error('解码后的JSON字符串仍然无效:', decodeError);
      return jsonString; // 返回原始字符串作为后备
    }
  }
}

// Helper function to run commands asynchronously
function runCommand(command, options) {
    console.log(`[Command Runner] Executing: ${command} in ${options.cwd}`);
    return new Promise((resolve, reject) => {
        const proc = exec(command, options, (error, stdout, stderr) => {
            if (error) {
                console.error(`[Command Runner] Error executing command: ${command}`);
                // Stderr is already logged by the event listener below
                // console.error(`Stderr: ${stderr}`); 
                error.stderr = stderr; // Attach for reporting
                reject(error);
            } else {
                console.log(`[Command Runner] Command completed successfully: ${command}`);
                // Stdout is logged by the event listener below
                // console.log(`Stdout: ${stdout}`); 
                resolve(stdout);
            }
        });
        
        // Log stdout/stderr in real-time
        proc.stdout?.on('data', (data) => {
            console.log(`[npm stdout] ${data.toString().trim()}`);
        });
        proc.stderr?.on('data', (data) => {
            // npm often uses stderr for progress/warnings, not just errors
            console.warn(`[npm stderr] ${data.toString().trim()}`); 
        });
    });
}

// --- Define persistent build workspace path ---
const buildWorkspaceDir = path.join(app.getPath('userData'), 'easy-window-build-workspace');
const buildMarkerFile = path.join(buildWorkspaceDir, '.install_marker');
const nodeModulesDir = path.join(buildWorkspaceDir, 'node_modules');

// Function to calculate file hash
function getFileHash(filePath) {
    if (!fs.existsSync(filePath)) return null;
    const fileBuffer = fs.readFileSync(filePath);
    const hashSum = crypto.createHash('sha256');
    hashSum.update(fileBuffer);
    return hashSum.digest('hex');
}

// Electron 初始化完成并准备创建浏览器窗口时，调用此方法
app.whenReady().then(() => {
  // 注册Vue项目构建处理程序
  registerVueBuilderHandlers();
  
  createWindow();

  ipcMain.handle('handle-export-project', async (event, files) => {
    if (!files || !Array.isArray(files)) {
      return { success: false, message: '无效的文件数据' };
    }

    const { canceled, filePath } = await dialog.showSaveDialog({
      title: '选择项目导出目录',
      buttonLabel: '导出到此处',
      // properties: ['openDirectory'] // showSaveDialog 通常不直接选目录，而是选保存文件名，我们这里把它当作目录
      // 改为让用户选择一个文件夹，然后我们在里面创建文件
    });

    if (canceled || !filePath) {
      console.log('用户取消了导出');
      return { success: false, message: '用户取消导出' };
    }

    // filePath 通常是带文件名的完整路径，我们需要其目录
    // 如果 showSaveDialog 被用来选择一个文件，我们取其目录
    // 如果我们假设用户会选择一个文件夹（虽然 showSaveDialog 不直接支持），就直接用 filePath
    // 更稳妥的做法是让用户选择一个 *文件夹* 使用 showOpenDialog

    // 使用 showOpenDialog 选择文件夹
    const dirResult = await dialog.showOpenDialog({ 
      title: '选择项目导出根目录', 
      properties: ['openDirectory', 'createDirectory'] 
    });

    if (dirResult.canceled || !dirResult.filePaths || dirResult.filePaths.length === 0) {
      console.log('用户取消了选择导出目录');
      return { success: false, message: '用户取消选择导出目录' };
    }

    const exportBasePath = dirResult.filePaths[0];
    let exportSuccess = false;
    let buildMessage = '';

    // --- 写入文件 --- 
    try {
      console.log(`开始导出项目到: ${exportBasePath}`);
      for (const file of files) {
        const fullPath = path.join(exportBasePath, file.relativePath);
        const dirName = path.dirname(fullPath);
        fs.mkdirSync(dirName, { recursive: true });
        fs.writeFileSync(fullPath, file.content);
      }
      console.log('项目文件写入成功！');
      exportSuccess = true;
    } catch (error) {
      console.error('写入项目文件时发生错误:', error);
      return { success: false, message: `导出失败: ${error.message}` };
    }

    // --- 如果文件写入成功，则尝试自动构建 --- 
    if (exportSuccess) {
      console.log('开始自动构建导出的项目...');
      // 注意：路径需要正确处理空格和特殊字符，Windows 下可能需要转义反斜杠
      const escapedPath = exportBasePath.replace(/\\/g, '\\');
      const command = `cd "${escapedPath}" && npm install && npm run build`;
      console.log(`Executing command: ${command}`);

      return new Promise((resolve) => {
        exec(command, { timeout: 300000 }, (error, stdout, stderr) => { // 增加超时时间到 5 分钟
          if (error) {
            console.error(`构建失败: ${error}`);
            console.error(`Stderr: ${stderr}`);
            resolve({
              success: false,
              message: `文件导出成功，但自动构建失败: ${error.message}. Stderr: ${stderr}. 请尝试手动运行 npm install && npm run build。`
            });
          } else {
            console.log(`构建成功！`);
            console.log(`Stdout: ${stdout}`);
            resolve({
              success: true,
              message: `项目已成功导出到 ${exportBasePath} 并自动构建完成！`
            });
          }
        });
      });
    } else {
      // 理论上不会执行到这里，因为写入失败时已经 return 了
      return { success: false, message: '导出失败（未知原因）' };
    }
  });

  // --- Handler for Miniblink Export (Async, Cached) ---
  ipcMain.handle('handle-export-for-miniblink', async (event, projectData) => {
    console.log('[Export Miniblink] 正在处理导出请求');
    
    // 确保必要的数据存在
    if (!projectData || !projectData.viewData || !projectData.viewData.components) {
      console.error('[Export Miniblink] 无效的项目数据');
      return { success: false, message: '无效的项目数据' };
    }
    
    const startTime = Date.now();
    const useVue3 = projectData.vue3Mode === true;
    let exportPath = projectData.viewData.exportPath || null;
    
    // 如果没有指定导出路径，打开对话框让用户选择
    if (!exportPath) {
      const dialogResult = await dialog.showOpenDialog({
        title: useVue3 ? '选择Vue3导出目录' : '选择Miniblink导出目录',
        properties: ['openDirectory']
      });
      
      if (dialogResult.canceled) {
        return { success: false, error: '导出已取消' };
      }
      
      exportPath = dialogResult.filePaths[0];
    }
    
    // 确保导出目录存在
    try {
      if (!fs.existsSync(exportPath)) {
        fs.mkdirSync(exportPath, { recursive: true });
      }
    } catch (error) {
      console.error('[Export Miniblink] 创建导出目录失败:', error);
      return { success: false, message: `创建导出目录失败: ${error.message || String(error)}` };
    }
    
    if (useVue3) {
      try {
        console.log('[Export Miniblink Vue3] 执行Vue3兼容模式导出');
        
        // 准备并记录组件数据
        const components = projectData.viewData.components || [];
        console.log('[Export Miniblink Vue3] 处理', components.length, '个组件');
        
        // 准备导出文件夹
        const projectName = projectData.viewData.projectName || 'EasyWindowApp';
        const buildDir = path.join(exportPath, `${projectName}-miniblink-vue3`);
        
        // 确保导出目录存在
        if (!fs.existsSync(buildDir)) {
          fs.mkdirSync(buildDir, { recursive: true });
        }
        
        // 准备公共目录
        const publicDir = path.join(buildDir, 'public');
        if (!fs.existsSync(publicDir)) {
          fs.mkdirSync(publicDir, { recursive: true });
        }
        
        // 读取Vue3兼容模板
        const templatePath = path.join(__dirname, '../src/templates/miniblink-vue3-compat.html.ejs');
        if (!fs.existsSync(templatePath)) {
          console.error('[Export Miniblink Vue3] Template file not found:', templatePath);
          return { 
            success: false, 
            message: '未找到Vue3兼容模板文件' 
          };
        }
        
        // 准备渲染数据
        const renderData = {
          productName: projectName,
          components: components,
          canvasSize: projectData.canvasSize || { width: 800, height: 600 } // 确保传递画布尺寸
        };
        
        console.log('[Export Miniblink Vue3] 准备模板数据，包含画布尺寸:', 
          renderData.canvasSize ? `${renderData.canvasSize.width}x${renderData.canvasSize.height}` : '使用默认值');
        
        // 读取并渲染EJS模板
        const templateContent = fs.readFileSync(templatePath, 'utf-8');
        const renderedContent = ejs.render(templateContent, renderData);
        
        // 写入HTML文件
        const outputPath = path.join(publicDir, 'index.html');
        fs.writeFileSync(outputPath, renderedContent, 'utf-8');
        
        console.log('[Export Miniblink Vue3] 生成导出文件...');
        
        // 创建示例README
        const readmePath = path.join(buildDir, 'README.md');
        const readmeContent = `# ${projectName} (Vue 3)

这是由 Easy Window 导出的 Miniblink Vue3 UI 项目。
导出时间: ${new Date().toLocaleString()}

## 使用方法

1. 将 public/index.html 文件加载到您的 Miniblink 项目中
2. 使用 MiniblinkCallback 函数接收事件通知
3. 查看 HTML 文件内的注释获取更多信息

## 组件列表

${components.map(comp => `- ${comp.type || '未知类型'} (ID: ${comp.id || '无ID'})`).join('\n')}
`;
        fs.writeFileSync(readmePath, readmeContent, 'utf-8');
        
        // 计算耗时
        const endTime = Date.now();
        const timeElapsed = ((endTime - startTime) / 1000).toFixed(2);
        
        // 返回导出结果
        return {
          success: true,
          message: '导出Vue3兼容模式文件成功',
          filePath: buildDir,
          timeElapsed: `${timeElapsed}s`
        };
      } catch (error) {
        console.error('[Export Miniblink Vue3] 导出失败:', error);
        return { 
          success: false, 
          message: `导出Vue3兼容模式失败: ${error.message || '未知错误'}` 
        };
      }
    } else {
      try {
        console.log('[Export Miniblink] 执行标准Miniblink导出');
        
        // 准备并记录组件数据
        const components = projectData.viewData.components || [];
        console.log('[Export Miniblink] 处理', components.length, '个组件');
        
        // 准备EJS渲染数据
        const serializedState = JSON.stringify({
          components,
          canvasSize: projectData.canvasSize || { width: 800, height: 600 }
        });
        
        const renderData = {
          serializedState: serializedState,
          canvasSize: projectData.canvasSize, // 添加这一行，确保传递 canvasSize
        };
        
        console.log('[Export Miniblink] 准备模板数据，包含画布尺寸:', 
          renderData.canvasSize ? `${renderData.canvasSize.width}x${renderData.canvasSize.height}` : '使用默认值');
        
        // 获取模板内容
        const templatePath = path.join(__dirname, '../src/templates/miniblink.html.ejs');
        let templateContent;
        
        if (fs.existsSync(templatePath)) {
          templateContent = fs.readFileSync(templatePath, 'utf-8');
          console.log('[Export Miniblink] 模板文件已找到');
        } else {
          console.error('[Export Miniblink] 找不到模板文件:', templatePath);
          return { success: false, message: '找不到模板文件' };
        }
        
        // 使用EJS渲染HTML
        const renderedHTML = ejs.render(templateContent, renderData);
        
        // 写入HTML文件
        const outputPath = path.join(exportPath, 'index.html');
        fs.writeFileSync(outputPath, renderedHTML, 'utf-8');
        console.log('[Export Miniblink] 导出HTML成功:', outputPath);
        
        // 计算耗时
        const endTime = Date.now();
        const timeElapsed = ((endTime - startTime) / 1000).toFixed(2);
        
        // 返回导出结果
        return {
          success: true,
          message: '导出Miniblink文件成功',
          filePath: outputPath,
          timeElapsed: `${timeElapsed}s`
        };
      } catch (error) {
        console.error('[Export Miniblink] 导出失败:', error);
        return { success: false, message: `导出失败: ${error.message || String(error)}` };
      }
    }
  });

  // --- Handler for exporting source code ---
  ipcMain.handle('handle-export-source', async (event, projectData) => {
    const startTime = Date.now();
    console.log('[Source Export] Received request');
    let currentStatus = '';
    const updateStatus = (status) => {
        currentStatus = status;
        console.log(`[Source Export] Status: ${status}`);
        event.sender.send('export-progress', { status });
    };

    try {
        // 1. Show dialog to select destination directory
        updateStatus('正在选择导出目录...');
        const dirResult = await dialog.showOpenDialog({ 
            title: '选择源代码导出位置', 
            properties: ['openDirectory', 'createDirectory'] 
        });

        if (dirResult.canceled || !dirResult.filePaths || dirResult.filePaths.length === 0) {
            console.log('[Source Export] User canceled directory selection');
            return { success: false, message: '用户取消选择导出目录' };
        }

        const exportDir = dirResult.filePaths[0];
        console.log(`[Source Export] Selected export directory: ${exportDir}`);

        // 2. Generate source files
        updateStatus('正在生成源码文件...');
        
        // Loop through templates and render them
        for (const { template, output } of projectData.templatesToRender) {
            const templateContent = getTemplateContent(template);
            const renderedContent = ejs.render(templateContent, projectData.viewData);
            const outputPath = path.join(exportDir, output);
            
            // Ensure subdirectory exists before writing
            const outputDir = path.dirname(outputPath);
            if (!fs.existsSync(outputDir)) {
                fs.mkdirSync(outputDir, { recursive: true });
            }
            fs.writeFileSync(outputPath, renderedContent);
            console.log(`[Source Export] Generated file: ${outputPath}`);
        }

        // 3. Complete export
        const elapsedTime = ((Date.now() - startTime) / 1000).toFixed(2);
        const successMessage = `源代码导出完成！用时 ${elapsedTime} 秒，文件保存在 ${exportDir}`;
        console.log(`[Source Export] ${successMessage}`);
        
        return { 
            success: true, 
            message: successMessage,
            filePath: exportDir
        };
    } catch (error) {
      console.error('[Source Export] Error during export process:', error);
      const errorMessage = error.stderr ? error.stderr.toString() : error.message;
      updateStatus(`错误: ${errorMessage.substring(0, 200)}...`); // Limit error message length
      return { success: false, message: `导出失败: ${errorMessage}` };
    }
  });
  // --- Source Export Handler End ---

  // --- Handler for exporting Miniblink HTML ---
  ipcMain.handle('handle-export-miniblink', async (event, projectData) => {
    try {
      console.log('Starting Miniblink export process...');
      console.log('Project data keys:', Object.keys(projectData));
      // 记录接收到的项目数据参数类型和内容
      console.log('Project data type:', typeof projectData); 
      console.log('Components array length:', projectData.components?.length || 0);
      console.log('Project name:', projectData.productName);
      
      const startTime = Date.now();
      
      const statusUpdate = (status) => {
        if (mainWindow) {
          mainWindow.webContents.send('export-status-update', { status });
        }
      };
      
      statusUpdate('开始导出...');
      
      // 如果未指定导出路径，让用户选择导出目录
      let exportPath = projectData.options?.exportPath;
      if (!exportPath) {
        const dialogResult = await dialog.showOpenDialog({
          title: '选择导出目录',
          properties: ['openDirectory']
        });
        
        if (dialogResult.canceled) {
          return { success: false, message: '用户取消选择导出目录' };
        }
        
        exportPath = dialogResult.filePaths[0];
      }
      
      console.log('[Export Miniblink] 导出路径:', exportPath);
      
      // 确保exportPath存在
      if (!fs.existsSync(exportPath)) {
        fs.mkdirSync(exportPath, { recursive: true });
      }
      
      // 处理组件数据 - 转换自定义组件类型
      if (projectData.components && Array.isArray(projectData.components)) {
        // 递归函数，处理所有组件和子组件
        const processComponent = (component) => {
          if (!component || typeof component !== 'object') return component;
          
          // 创建新对象，避免修改原始对象
          const newComponent = {...component};
          
          // 转换自定义组件类型
          if (newComponent.type && typeof newComponent.type === 'string') {
            if (newComponent.type.startsWith('ew-')) {
              newComponent.type = newComponent.type.replace('ew-', 'el-');
              console.log(`[Export Miniblink] 转换组件类型: ${component.type} -> ${newComponent.type}`);
            }
          }
          
          // 处理子组件
          if (newComponent.children && Array.isArray(newComponent.children)) {
            newComponent.children = newComponent.children.map(processComponent);
          }
          
          return newComponent;
        };
        
        // 处理所有组件
        projectData.components = projectData.components.map(processComponent);
      }
      
      statusUpdate('准备导出目录...');
      
      // 准备导出文件夹
      const projectName = projectData.projectName || 'EasyWindowApp';
      const buildDir = path.join(exportPath, `${projectName}-miniblink`);
      
      // 确保导出目录存在
      if (!fs.existsSync(buildDir)) {
        fs.mkdirSync(buildDir, { recursive: true });
      }
      
      // 检查组件数据有效性
      if (!projectData.components || !Array.isArray(projectData.components) || projectData.components.length === 0) {
        console.error('Invalid components data:', projectData.components);
        return { success: false, error: '无效的组件数据' };
      }
      
      statusUpdate('处理组件数据...');
      
      // 获取外部依赖
      try {
        // 使用本地EJS模板导出HTML
        const publicDir = path.join(buildDir, 'public');
        if (!fs.existsSync(publicDir)) {
          fs.mkdirSync(publicDir, { recursive: true });
        }
        
        // 读取miniblink.html.ejs模板
        const templatePath = path.join(__dirname, '../src/templates/miniblink.html.ejs');
        if (!fs.existsSync(templatePath)) {
          console.error('Template file not found:', templatePath);
          // 尝试寻找替代位置或创建内联模板
          // ...
        }
        
        // 准备EJS渲染数据
        const renderData = {
          productName: projectName,
          components: projectData.components,
          elementPlusStyles: '/* 直接使用CDN引入样式 */\n@import url("https://unpkg.com/element-plus/dist/index.css");', 
          elementPlusRuntime: 'document.write(\'<script src="https://unpkg.com/element-plus"><\\/script>\');', 
          vueRuntime: 'document.write(\'<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"><\\/script>\');',
          componentStyles: projectData.componentStyles || '',
          // 添加Vue3模式标志
          isVue3Mode: !!projectData.vue3Mode
        };
        
        // 读取并渲染EJS模板
        const templateContent = getTemplateContent('miniblink.html.ejs');
        const renderedContent = ejs.render(templateContent, prepareEJSData(renderData));
        
        // 写入HTML文件
        const outputPath = path.join(publicDir, 'index.html');
        fs.writeFileSync(outputPath, renderedContent);
        
        statusUpdate('生成导出文件...');
        
        // 创建示例README
        const readmePath = path.join(buildDir, 'README.md');
        const readmeContent = `# ${projectName}

这是由 Easy Window 导出的 Miniblink UI 项目。
导出时间: ${new Date().toLocaleString()}

## 使用方法

1. 将 public/index.html 文件加载到您的 Miniblink 项目中
2. 使用 MiniblinkCallback 函数接收事件通知
3. 查看 HTML 文件内的注释获取更多信息

## 组件列表

${projectData.components.map(comp => `- ${comp.type || '未知类型'} (ID: ${comp.id || '无ID'})`).join('\n')}
`;
        fs.writeFileSync(readmePath, readmeContent, 'utf-8');
      } catch (error) {
        console.error('Error processing template:', error);
        return { success: false, error: `处理模板失败: ${error.message || '未知错误'}` };
      }
      
      statusUpdate('导出完成');
      
      // 计算耗时
      const endTime = Date.now();
      const timeElapsed = ((endTime - startTime) / 1000).toFixed(2);
      
      // 返回导出结果
      return {
        success: true,
        filePath: buildDir,
        timeElapsed: `${timeElapsed}s`
      };
    } catch (error) {
      console.error('Error during Miniblink export:', error);
      return { 
        success: false, 
        error: error.message || '导出过程中发生未知错误' 
      };
    }
  });
  
  // --- Handler for saving files ---
  ipcMain.handle('save-file', async (event, { content, fileName, showDialog }) => {
    try {
      // 如果没有提供文件名，或者明确要求显示对话框，则显示保存对话框
      let filePath = '';
      
      if (!fileName || showDialog === true) {
        // 如果没有文件名，显示保存对话框，默认使用index.html
        const result = await dialog.showSaveDialog({
          title: '保存文件',
          defaultPath: path.join(app.getPath('documents'), fileName || 'index.html'),
          buttonLabel: '保存',
          filters: [
            { name: 'HTML文件', extensions: ['html'] }
          ]
        });
        
        if (result.canceled) {
          return { success: false, message: '用户取消了操作' };
        }
        
        filePath = result.filePath;
      } else if (path.isAbsolute(fileName)) {
        // 如果提供了绝对路径，直接使用
        filePath = fileName;
      } else {
        // 使用默认目录和提供的文件名
        filePath = path.join(app.getPath('documents'), fileName);
      }
      
      // 确保目录存在
      const dirPath = path.dirname(filePath);
      if (!fs.existsSync(dirPath)) {
        fs.mkdirSync(dirPath, { recursive: true });
      }
      
      // 写入文件
      fs.writeFileSync(filePath, content, 'utf-8');
      
      return {
        success: true,
        message: '文件保存成功',
        filePath
      };
    } catch (error) {
      console.error('保存文件失败:', error);
      return {
        success: false,
        message: `保存文件失败: ${error.message}`,
        error: error.message
      };
    }
  });
  
  // --- Handler for saving HTML files, with dialog ---
  ipcMain.handle('save-html-file', async (event, { html, path, filename, showSaveDialog }) => {
    try {
      console.log('[主进程] 开始保存HTML文件:', { path, filename, showSaveDialog });
      
      // 优先考虑是否需要显示保存对话框
      let filePath = '';
      
      // 如果明确要求显示保存对话框或者未提供路径，则显示对话框
      if (showSaveDialog === true || !path) {
        console.log('[主进程] 显示保存对话框');
        
        // 准备对话框默认路径
        let defaultPath;
        if (path && filename) {
          defaultPath = path.includes(filename) ? path : require('path').join(path, filename || 'index.html');
        } else if (path) {
          defaultPath = path;
        } else {
          defaultPath = require('path').join(app.getPath('documents'), filename || 'index.html');
        }
        
        // 显示保存对话框
        const result = await dialog.showSaveDialog({
          title: '保存HTML文件',
          defaultPath: defaultPath,
          buttonLabel: '保存',
          filters: [
            { name: 'HTML文件', extensions: ['html'] }
          ]
        });
        
        // 用户取消了操作
        if (result.canceled) {
          console.log('[主进程] 用户取消了保存操作');
          return { success: false, message: '用户取消了保存操作' };
        }
        
        filePath = result.filePath;
      } else {
        // 如果提供了路径和文件名但不显示对话框
        filePath = path.includes(filename) ? path : require('path').join(path, filename || 'index.html');
      }
      
      console.log('[主进程] 将保存文件到:', filePath);
      
      // 确保目录存在
      const dirPath = require('path').dirname(filePath);
      if (!fs.existsSync(dirPath)) {
        fs.mkdirSync(dirPath, { recursive: true });
      }
      
      // 写入HTML文件
      fs.writeFileSync(filePath, html, 'utf-8');
      
      console.log('[主进程] HTML文件保存成功');
      
      return {
        success: true,
        message: 'HTML文件保存成功',
        filePath
      };
    } catch (error) {
      console.error('[主进程] 保存HTML文件失败:', error);
      return {
        success: false,
        message: `保存HTML文件失败: ${error.message}`,
        error: error.message
      };
    }
  });
  
  // --- Handler for opening directories ---
  ipcMain.handle('open-directory', async (event, options) => {
    try {
      const { path } = options;
      let dirPath = path;
      
      // 如果是文件路径，则获取其所在目录
      if (fs.existsSync(path) && fs.statSync(path).isFile()) {
        dirPath = require('path').dirname(path);
      }
      
      // 检查目录是否存在
      if (!fs.existsSync(dirPath)) {
        return { success: false, message: `目录不存在: ${dirPath}` };
      }
      
      // 打开目录
      shell.openPath(dirPath);
      
      return { success: true };
    } catch (error) {
      console.error('打开目录失败:', error);
      return { success: false, message: `打开目录失败: ${error.message}` };
    }
  });

  // --- Handler for opening files ---
  ipcMain.handle('open-file', async (event, options) => {
    try {
      const { path } = options;
      
      // 检查文件是否存在
      if (!fs.existsSync(path)) {
        return { success: false, message: `文件不存在: ${path}` };
      }
      
      // 打开文件
      shell.openPath(path);
      
      return { success: true };
    } catch (error) {
      console.error('打开文件失败:', error);
      return { success: false, message: `打开文件失败: ${error.message}` };
    }
  });

  // 打开文件对话框处理
  ipcMain.handle('show-save-dialog', async (event, options) => {
    try {
      return await dialog.showSaveDialog({
        title: options.title || '保存文件',
        defaultPath: options.defaultPath || app.getPath('documents'),
        buttonLabel: options.buttonLabel || '保存',
        filters: options.filters || [
          { name: '所有文件', extensions: ['*'] }
        ]
      });
    } catch (error) {
      console.error('保存对话框错误:', error);
      return { canceled: true, error: error.message };
    }
  });

  // 打开文件夹
  ipcMain.handle('open-folder', async (event, folderPath) => {
    try {
      if (!folderPath) {
        throw new Error('文件夹路径不能为空');
      }
      
      // 确保文件夹存在
      if (!fs.existsSync(folderPath)) {
        throw new Error('文件夹不存在');
      }
      
      // 打开文件夹
      if (process.platform === 'win32') {
        await exec(`explorer "${folderPath}"`);
      } else if (process.platform === 'darwin') {
        await exec(`open "${folderPath}"`);
      } else if (process.platform === 'linux') {
        await exec(`xdg-open "${folderPath}"`);
      } else {
        throw new Error('不支持的操作系统');
      }
      
      return { success: true };
    } catch (error) {
      console.error('打开文件夹错误:', error);
      return { success: false, error: error.message };
    }
  });

  // --- Handler for exporting Miniblink Vue3 HTML ---
  ipcMain.handle('handle-export-miniblink-vue3', async (event, projectData) => {
    try {
      console.log('Starting Miniblink Vue3 export process...');
      console.log('Project data keys:', Object.keys(projectData));
      // 记录接收到的项目数据参数类型和内容
      console.log('Project data type:', typeof projectData); 
      console.log('Components array length:', projectData.components?.length || 0);
      console.log('Project name:', projectData.projectName);
      
      const startTime = Date.now();
      
      const statusUpdate = (status) => {
        event.sender.send('export-status-update', { status });
      };
      
      statusUpdate('开始Vue3导出...');
      
      // 如果未指定导出路径，让用户选择导出目录
      let exportPath = projectData.options?.exportPath;
      if (!exportPath) {
        const dialogResult = await dialog.showOpenDialog({
          title: '选择Vue3导出目录',
          properties: ['openDirectory']
        });
        
        if (dialogResult.canceled) {
          return { success: false, error: '导出已取消' };
        }
        
        exportPath = dialogResult.filePaths[0];
      }
      
      statusUpdate('准备Vue3导出目录...');
      
      // 准备导出文件夹
      const projectName = projectData.projectName || 'EasyWindowApp';
      const buildDir = path.join(exportPath, `${projectName}-miniblink-vue3`);
      
      // 确保导出目录存在
      if (!fs.existsSync(buildDir)) {
        fs.mkdirSync(buildDir, { recursive: true });
      }
      
      // 检查组件数据有效性
      if (!projectData.components || !Array.isArray(projectData.components) || projectData.components.length === 0) {
        console.error('Invalid components data:', projectData.components);
        return { success: false, error: '无效的组件数据' };
      }
      
      statusUpdate('处理Vue3组件数据...');
      
      // 获取外部依赖
      try {
        // 使用本地EJS模板导出HTML
        const publicDir = path.join(buildDir, 'public');
        if (!fs.existsSync(publicDir)) {
          fs.mkdirSync(publicDir, { recursive: true });
        }
        
        // 读取miniblink.html.ejs模板
        const templatePath = path.join(__dirname, '../src/templates/miniblink.html.ejs');
        if (!fs.existsSync(templatePath)) {
          console.error('Template file not found:', templatePath);
          // 尝试寻找替代位置
          const altTemplatePath = path.join(__dirname, '../dist/templates/miniblink.html.ejs');
          if (fs.existsSync(altTemplatePath)) {
            templatePath = altTemplatePath;
          } else {
            return { success: false, error: '未找到模板文件' };
          }
        }
        
        // 准备EJS渲染数据
        const renderData = {
          productName: projectName,
          components: projectData.components,
          elementPlusStyles: '/* 直接使用CDN引入样式 */\n@import url("https://unpkg.com/element-plus/dist/index.css");', 
          elementPlusRuntime: 'document.write(\'<script src="https://unpkg.com/element-plus"><\\/script>\');', 
          vueRuntime: 'document.write(\'<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"><\\/script>\');',
          componentStyles: projectData.componentStyles || '',
          // 添加Vue3模式标志
          isVue3Mode: !!projectData.vue3Mode
        };
        
        // 读取并渲染EJS模板
        const templateContent = getTemplateContent('miniblink.html.ejs');
        const renderedContent = ejs.render(templateContent, prepareEJSData(renderData));
        
        // 写入HTML文件
        const outputPath = path.join(publicDir, 'index.html');
        fs.writeFileSync(outputPath, renderedContent);
        
        statusUpdate('生成Vue3导出文件...');
        
        // 创建示例README
        const readmePath = path.join(buildDir, 'README.md');
        const readmeContent = `# ${projectName} (Vue 3)

这是由 Easy Window 导出的 Miniblink Vue3 UI 项目。
导出时间: ${new Date().toLocaleString()}

## 使用方法

1. 将 public/index.html 文件加载到您的 Miniblink 项目中
2. 使用 MiniblinkCallback 函数接收事件通知
3. 查看 HTML 文件内的注释获取更多信息

## 组件列表

${projectData.components.map(comp => `- ${comp.type || '未知类型'} (ID: ${comp.id || '无ID'})`).join('\n')}
`;
        fs.writeFileSync(readmePath, readmeContent, 'utf-8');
      } catch (error) {
        console.error('Error processing template:', error);
        return { success: false, error: `处理模板失败: ${error.message || '未知错误'}` };
      }
      
      statusUpdate('Vue3导出完成');
      
      // 计算耗时
      const endTime = Date.now();
      const timeElapsed = ((endTime - startTime) / 1000).toFixed(2);
      
      // 返回导出结果
      return {
        success: true,
        filePath: buildDir,
        timeElapsed: `${timeElapsed}s`
      };
    } catch (error) {
      console.error('Error during Miniblink Vue3 export:', error);
      return { 
        success: false, 
        error: error.message || '导出过程中发生未知错误' 
      };
    }
  });

  app.on('activate', function () {
    // 在 macOS 上，当点击 dock 图标并且没有其他窗口打开时，
    // 通常会在应用程序中重新创建一个窗口。
    if (BrowserWindow.getAllWindows().length === 0) createWindow();
  });
});

// 除 macOS 外，当所有窗口都关闭时退出应用程序。
app.on('window-all-closed', function () {
  if (process.platform !== 'darwin') app.quit();
});

// 在此文件中，可以包含应用程序特定主进程的其他逻辑。
// 也可以将其放入单独的文件中，然后在此处 require() 它们。 

// 准备EJS渲染数据，确保JSON数据不会被HTML实体编码
function prepareEJSData(data) {
  // 创建一个新对象，避免修改原始数据
  const processed = { ...data };
  
  // 特殊处理components数组，确保它不会被HTML实体编码
  if (processed.components && Array.isArray(processed.components)) {
    // 不需要做额外处理，因为我们在模板中使用<%- %>而不是<%= %>
    console.log('准备组件数据，共', processed.components.length, '个组件');
  }
  
  // 处理CDN链接，确保它们不会被HTML实体编码
  if (processed.vueRuntime && typeof processed.vueRuntime === 'string') {
    // 去除可能有的HTML实体
    processed.vueRuntime = decodeHtmlEntities(processed.vueRuntime);
  }
  
  if (processed.elementPlusRuntime && typeof processed.elementPlusRuntime === 'string') {
    processed.elementPlusRuntime = decodeHtmlEntities(processed.elementPlusRuntime);
  }
  
  if (processed.elementPlusStyles && typeof processed.elementPlusStyles === 'string') {
    processed.elementPlusStyles = decodeHtmlEntities(processed.elementPlusStyles);
  }
  
  return processed;
}

// 处理确保目录存在的IPC消息
ipcMain.handle('ensure-directory-exists', async (event, dirPath) => {
  console.log('IPC: 确保目录存在:', dirPath);
  try {
    if (!fs.existsSync(dirPath)) {
      await fsPromises.mkdir(dirPath, { recursive: true });
      console.log('目录创建成功:', dirPath);
    } else {
      console.log('目录已存在:', dirPath);
    }
    return { success: true };
  } catch (error) {
    console.error('创建目录失败:', error);
    return { 
      success: false, 
      error: error.message || String(error)
    };
  }
});

// 处理 Miniblink HTML 导出
ipcMain.handle('handle-miniblink-html-export', async (event, data) => {
  try {
    console.log('[主进程] 处理Miniblink HTML导出请求');
    
    // 检查参数
    if (!data) {
      console.error('[主进程] 导出数据为空');
      return { success: false, message: '导出失败：导出数据为空' };
    }
    
    // 检查输出路径
    let outputPath = data.outputPath;
    if (!outputPath) {
      // 如果没有提供输出路径，则生成一个默认路径
      const defaultDirectory = path.join(app.getPath('documents'), 'Easy Window');
      if (!fs.existsSync(defaultDirectory)) {
        fs.mkdirSync(defaultDirectory, { recursive: true });
      }
      
      const defaultFileName = `miniblink_export_${new Date().toISOString().split('T')[0].replace(/-/g, '')}.html`;
      outputPath = path.join(defaultDirectory, defaultFileName);
      console.log('[主进程] 未提供输出路径，使用默认路径:', outputPath);
    }
    
    // 规范化路径（统一使用正斜杠）
    outputPath = outputPath.replace(/\\/g, '/');
    
    // 修复错误的路径格式（如果路径中有.html/index.html）
    if (outputPath.includes('.html/')) {
      outputPath = outputPath.split('.html/')[0] + '.html';
      console.log('[主进程] 修复后的输出路径:', outputPath);
    }
    
    // 确保目录存在
    const outputDir = path.dirname(outputPath);
    if (!fs.existsSync(outputDir)) {
      fs.mkdirSync(outputDir, { recursive: true });
    }
    
    // 处理组件数据
    let components = [];
    let productName = 'UI Generated by Easy Window';
    let canvasSize = { width: 800, height: 600 };
    
    try {
      // 如果使用JSON文件
      if (data.useJsonFile && data.jsonFilePath) {
        console.log('[主进程] 从JSON文件读取组件数据:', data.jsonFilePath);
        
        // 检查文件是否存在
        if (!fs.existsSync(data.jsonFilePath)) {
          console.error('[主进程] JSON文件不存在:', data.jsonFilePath);
          return { 
            success: false, 
            message: `JSON文件不存在: ${data.jsonFilePath}` 
          };
        }
        
        // 读取JSON文件
        try {
          const jsonContent = fs.readFileSync(data.jsonFilePath, 'utf-8');
          const jsonData = JSON.parse(jsonContent);
          
          // 提取数据
          components = jsonData.components || [];
          productName = jsonData.projectName || productName;
          canvasSize = jsonData.canvasSize || canvasSize;
          
          console.log('[主进程] 从JSON文件成功读取组件数据，组件数量:', components.length);
        } catch (jsonError) {
          console.error('[主进程] 解析JSON文件失败:', jsonError);
          return { 
            success: false, 
            message: `解析JSON文件失败: ${jsonError.message}` 
          };
        }
      }
      // 如果提供了直接的组件数据
      else if (data.components) {
        components = data.components;
        productName = data.projectName || productName;
        canvasSize = data.canvasSize || canvasSize;
      } 
      // 如果提供了viewData对象
      else if (data.viewData) {
        components = data.viewData.components || [];
        productName = data.viewData.productName || productName;
        canvasSize = data.viewData.canvasSize || canvasSize;
      }
      
      console.log('[主进程] 成功解析组件数据，组件数量:', components.length);
    } catch (dataError) {
      console.error('[主进程] 解析组件数据失败:', dataError);
      return { 
        success: false, 
        message: `解析组件数据失败: ${dataError.message}` 
      };
    }
    
    // 生成HTML内容
    try {
      console.log('[主进程] 开始生成HTML');
      
      // 使用内置模板生成HTML，不读取外部文件
      const templateContent = `<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title><%= productName %></title>
  <script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
  <link rel="stylesheet" href="https://unpkg.com/element-plus/dist/index.css">
  <script src="https://unpkg.com/element-plus"></script>
  <style>
    body { font-family: Arial, sans-serif; margin: 0; padding: 0; }
    .app-container { 
      width: <%= canvasSize.width %>px; 
      height: <%= canvasSize.height %>px; 
      margin: 0 auto; 
      position: relative; 
      overflow: auto;
    }
    .component-container {
      position: relative;
    }
  </style>
</head>
<body>
  <div id="app"></div>
  <script>
    window.appData = {
      components: <%- JSON.stringify(components) %>,
      canvasSize: <%- JSON.stringify(canvasSize) %>
    };
    
    const app = Vue.createApp({
      template: \`<div class="app-container"></div>\`,
      setup() {
        return {};
      }
    });
    
    app.use(ElementPlus);
    app.mount('#app');
  </script>
</body>
</html>`;
      
      // 渲染模板
      const ejs = require('ejs');
      const renderedHTML = ejs.render(templateContent, {
        components,
        productName,
        canvasSize
      });
      
      // 保存到文件
      fs.writeFileSync(outputPath, renderedHTML, 'utf-8');
      
      console.log('[主进程] HTML生成完成，已保存到:', outputPath);
      
      return {
        success: true,
        message: '导出成功',
        filePath: outputPath
      };
    } catch (renderError) {
      console.error('[主进程] 生成HTML失败:', renderError);
      return {
        success: false,
        message: `生成HTML失败: ${renderError.message}`
      };
    }
  } catch (error) {
    console.error('[主进程] 处理导出请求失败:', error);
    return {
      success: false,
      message: `处理导出请求失败: ${error.message}`
    };
  }
});

// 写入临时文件处理
ipcMain.handle('write-temp-file', async (event, { path, content }) => {
  try {
    console.log('[主进程] 写入临时文件:', path);
    
    // 确保目录存在
    const dirPath = require('path').dirname(path);
    if (!fs.existsSync(dirPath)) {
      fs.mkdirSync(dirPath, { recursive: true });
    }
    
    // 写入文件
    fs.writeFileSync(path, content, 'utf-8');
    
    return {
      success: true,
      message: '临时文件写入成功',
      path
    };
  } catch (error) {
    console.error('[主进程] 写入临时文件失败:', error);
    return {
      success: false,
      message: `写入临时文件失败: ${error.message}`,
      error: error.message
    };
  }
});

// 删除临时文件处理
ipcMain.handle('delete-temp-file', async (event, filePath) => {
  try {
    console.log('[主进程] 删除临时文件:', filePath);
    
    if (fs.existsSync(filePath)) {
      fs.unlinkSync(filePath);
      return {
        success: true,
        message: '临时文件删除成功'
      };
    } else {
      return {
        success: true,
        message: '文件不存在，无需删除'
      };
    }
  } catch (error) {
    console.error('[主进程] 删除临时文件失败:', error);
    return {
      success: false,
      message: `删除临时文件失败: ${error.message}`,
      error: error.message
    };
  }
});

// 处理 Miniblink HTML 导出 (base64版本)
ipcMain.handle('handle-miniblink-html-export-base64', async (event, data) => {
  try {
    console.log('[主进程] 处理base64编码的Miniblink HTML导出请求');
    
    // 检查参数
    if (!data) {
      console.error('[主进程] 导出数据为空');
      return { success: false, message: '导出失败：导出数据为空' };
    }
    
    // 提取基本数据
    const { outputPath, projectName, canvasWidth, canvasHeight, componentsBase64 } = data;
    
    // 验证必要参数
    if (!outputPath) {
      console.error('[主进程] 缺少输出路径');
      return { success: false, message: '导出失败：缺少输出路径' };
    }
    
    if (!componentsBase64) {
      console.error('[主进程] 缺少组件数据');
      return { success: false, message: '导出失败：缺少组件数据' };
    }
    
    // 设置默认值
    const finalProjectName = projectName || 'Miniblink UI';
    const canvasSize = {
      width: canvasWidth || 800,
      height: canvasHeight || 600
    };
    
    // 解码base64组件数据
    let components = [];
    try {
      const jsonString = decodeURIComponent(escape(Buffer.from(componentsBase64, 'base64').toString('utf8')));
      components = JSON.parse(jsonString);
      console.log('[主进程] 成功解码组件数据，组件数量:', components.length);
    } catch (decodeError) {
      console.error('[主进程] 解码组件数据失败:', decodeError);
      return { 
        success: false, 
        message: `解码组件数据失败: ${decodeError.message}` 
      };
    }
    
    // 规范化路径，确保输出目录存在
    let finalOutputPath = outputPath.replace(/\\/g, '/');
    const outputDir = path.dirname(finalOutputPath);
    
    if (!fs.existsSync(outputDir)) {
      fs.mkdirSync(outputDir, { recursive: true });
      console.log('[主进程] 创建输出目录:', outputDir);
    }
    
    // 使用内置模板生成HTML
    const templateContent = `<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>${finalProjectName}</title>
  <script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
  <link rel="stylesheet" href="https://unpkg.com/element-plus/dist/index.css">
  <script src="https://unpkg.com/element-plus"></script>
  <style>
    body { font-family: Arial, sans-serif; margin: 0; padding: 0; }
    .app-container { 
      width: ${canvasSize.width}px; 
      height: ${canvasSize.height}px; 
      margin: 0 auto; 
      position: relative; 
      overflow: auto;
    }
    .component-container {
      position: relative;
    }
  </style>
</head>
<body>
  <div id="app"></div>
  <script>
    window.appData = {
      components: ${JSON.stringify(components)},
      canvasSize: ${JSON.stringify(canvasSize)}
    };
    
    const app = Vue.createApp({
      template: \`<div class="app-container"></div>\`,
      setup() {
        return {};
      }
    });
    
    // 添加全局样式修复
    document.head.insertAdjacentHTML('beforeend', \`
      <style>
        /* 强制修复单选框和多选框样式 */
        .el-radio, .el-checkbox,
        label.el-radio, label.el-checkbox {
          width: auto !important;
          height: auto !important;
          max-width: none !important;
          max-height: none !important;
          position: relative !important;
          display: flex !important;
          align-items: center !important;
          margin-right: 10px !important;
        }
        
        /* 修复组内元素可能被覆盖的问题 */
        .el-radio-group > *, .el-checkbox-group > * {
          position: relative !important;
          width: auto !important;
          height: auto !important;
          z-index: auto !important;
        }
        
        /* 直接覆盖所有label元素 */
        label[class*='el-'] {
          width: auto !important;
          height: auto !important;
          position: relative !important;
        }
      </style>
    \`);
    
    app.use(ElementPlus);
    app.mount('#app');
  </script>
</body>
</html>`;
    
    // 写入HTML文件
    try {
      fs.writeFileSync(finalOutputPath, templateContent, 'utf-8');
      console.log('[主进程] HTML文件已保存到:', finalOutputPath);
      
      return {
        success: true,
        message: '导出成功',
        filePath: finalOutputPath
      };
    } catch (writeError) {
      console.error('[主进程] 写入HTML文件失败:', writeError);
      return { 
        success: false, 
        message: `写入HTML文件失败: ${writeError.message}` 
      };
    }
  } catch (error) {
    console.error('[主进程] 处理base64导出请求失败:', error);
    return {
      success: false,
      message: `处理导出请求失败: ${error.message}`
    };
  }
});

// --- 处理每个组件的工具函数，递归处理子组件 ---
function processComponent(component) {
  if (!component || typeof component !== 'object') return component;
  
  // 创建新对象，避免修改原始对象
  const newComponent = {...component};
  
  // 转换自定义组件类型
  if (newComponent.type && typeof newComponent.type === 'string') {
    if (newComponent.type.startsWith('ew-')) {
      newComponent.type = newComponent.type.replace('ew-', 'el-');
    }
  }
  
  // 处理props.datas对象
  if (newComponent.props && newComponent.props.datas && typeof newComponent.props.datas === 'object') {
    // 将datas中的属性复制到props顶层
    Object.keys(newComponent.props.datas).forEach(key => {
      if (newComponent.props[key] === undefined) {
        newComponent.props[key] = newComponent.props.datas[key];
      }
    });
  }
  
  // 处理子组件
  if (newComponent.children && Array.isArray(newComponent.children)) {
    newComponent.children = newComponent.children.map(processComponent);
  }
  
  return newComponent;
}

// 处理Miniblink直接导出（避免序列化问题）
ipcMain.handle('handle-miniblink-direct-export', async (event, data) => {
  try {
    const { basicData, components } = data;
    const { 
      outputPath, 
      projectName, 
      canvasWidth, 
      canvasHeight,
      canvasBackgroundColor,
      canvasBorderWidth,
      canvasBorderStyle,
      canvasBorderColor,
      canvasBorderRadius
    } = basicData;
    
    console.log('导出路径:', outputPath);
    console.log('画布样式:', {
      背景色: canvasBackgroundColor || '#ffffff',
      边框宽度: canvasBorderWidth || '1px',
      边框样式: canvasBorderStyle || 'solid',
      边框颜色: canvasBorderColor || '#cccccc',
      边框圆角: canvasBorderRadius || '0px'
    });
    
    // 确保目录存在 - 使用更健壮的目录路径提取
    let dirPath;
    try {
      // 标准化路径 (统一使用正斜杠)
      const normalizedPath = outputPath.replace(/\\/g, '/');
      // 提取目录路径
      dirPath = path.dirname(normalizedPath);
      
      console.log('目标目录:', dirPath);
      
      // 检查目录是否存在，不存在则创建
      if (!fs.existsSync(dirPath)) {
        console.log('创建目录:', dirPath);
        // 使用recursive:true确保创建所有必要的父目录
        fs.mkdirSync(dirPath, { recursive: true });
      } else {
        console.log('目录已存在:', dirPath);
      }
    } catch (dirError) {
      console.error('目录处理出错:', dirError);
      return { 
        success: false, 
        message: `目录创建失败: ${dirError.message}. 请确保有权限创建此目录，或选择其他保存位置。` 
      };
    }
    
    // 获取模板内容
    let templatePath;
    let templateContent;
    try {
      templatePath = path.join(__dirname, '../src/templates/miniblink.html.ejs');
      console.log('模板路径:', templatePath);
      
      if (!fs.existsSync(templatePath)) {
        console.warn('默认模板路径不存在，尝试备用路径');
        // 尝试备用路径 (兼容生产环境)
        const altPaths = [
          path.join(__dirname, '../templates/miniblink.html.ejs'),
          path.join(__dirname, 'templates/miniblink.html.ejs'),
          path.join(__dirname, '../../src/templates/miniblink.html.ejs')
        ];
        
        for (const altPath of altPaths) {
          if (fs.existsSync(altPath)) {
            templatePath = altPath;
            console.log('使用备用模板路径:', templatePath);
            break;
          }
        }
      }
      
      if (!fs.existsSync(templatePath)) {
        throw new Error(`找不到模板文件: ${templatePath}`);
      }
      
      templateContent = fs.readFileSync(templatePath, 'utf-8');
    } catch (err) {
      console.error('读取模板文件失败:', err);
      
      // 回退到简单模板(内置，不需要外部文件)
      console.log('使用内置简单模板');
      templateContent = null;
    }
    
    // 处理组件数据 - 递归处理每个组件和子组件
    const processedComponents = Array.isArray(components) ? components.map(processComponent) : [];
    
    // 准备渲染数据
    const viewData = {
      components: processedComponents,
      productName: projectName || 'Easy Window UI',
      canvasSize: {
        width: canvasWidth || 800,
        height: canvasHeight || 600
      },
      canvasStyle: {
        backgroundColor: canvasBackgroundColor || '#ffffff',
        borderWidth: canvasBorderWidth ? `${canvasBorderWidth}px` : '1px',
        borderStyle: canvasBorderStyle || 'solid',
        borderColor: canvasBorderColor || '#cccccc',
        borderRadius: canvasBorderRadius ? `${canvasBorderRadius}px` : '0px'
      },
      componentStyles: '' // 可选的自定义样式
    };
    
    // 渲染HTML内容
    let renderedHTML;
    
    if (templateContent) {
      try {
        // 尝试使用外部模板渲染
        renderedHTML = ejs.render(templateContent, viewData);
        console.log('模板渲染成功');
      } catch (renderErr) {
        console.error('模板渲染失败，改用内置模板:', renderErr);
        templateContent = null; // 回退到内置模板
      }
    }
    
    // 如果外部模板渲染失败，使用内置模板
    if (!templateContent) {
      console.log('使用内置模板');
      // 简单内置模板 (与之前相同，确保能够正确渲染组件)
      renderedHTML = `<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>${projectName || 'Easy Window UI'}</title>
  <!-- Vue 3 -->
  <script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
  <!-- Element Plus -->
  <link rel="stylesheet" href="https://unpkg.com/element-plus/dist/index.css">
  <script src="https://unpkg.com/element-plus"></script>
  <style>
    body, html { 
      margin: 0; 
      padding: 0; 
      height: 100%; 
      font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", sans-serif; 
      display: flex;
      justify-content: center;
      align-items: center;
      background-color: #f5f7fa;
    }
    #app { 
      width: ${canvasWidth || 800}px; 
      height: ${canvasHeight || 600}px; 
      position: relative;
      margin: 0 auto;
      overflow: hidden;
      background-color: ${canvasBackgroundColor || '#ffffff'};
      border: ${canvasBorderWidth || 1}px ${canvasBorderStyle || 'solid'} ${canvasBorderColor || '#cccccc'};
      border-radius: ${canvasBorderRadius || 0}px;
      box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 12px;
      box-sizing: border-box;
    }
    
    /* 根元素样式 - 确保画布样式也应用到这里 */
    [data-component-id="root"] {
      width: 100% !important;
      height: 100% !important;
      position: relative !important;
      background-color: ${canvasBackgroundColor || '#ffffff'} !important;
      border-radius: ${canvasBorderRadius || 0}px !important;
      border: ${canvasBorderWidth || 1}px ${canvasBorderStyle || 'solid'} ${canvasBorderColor || '#cccccc'} !important;
      box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 12px !important;
      box-sizing: border-box !important;
      overflow: hidden !important;
    }
    
    /* 确保元素绝对定位 */
    [data-component-id] { 
      box-sizing: border-box !important; 
      position: absolute !important;
    }
    
    /* ===== 单选框和多选框特殊处理 ===== */
    /* 单选框组和多选框组容器 */
    .el-radio-group, .el-checkbox-group {
      display: flex !important;
      flex-direction: column !important;
      gap: 10px !important;
      align-items: flex-start !important;
    }
    
    /* 单选框和多选框本身 */
    .el-radio, .el-checkbox {
      margin-right: 0 !important;
      margin-bottom: 0 !important;
      width: auto !important;
      height: auto !important;
      position: relative !important;
      display: flex !important;
      align-items: center !important;
      z-index: auto !important;
    }
    
    /* 组内的单选框和多选框 */
    .el-radio-group > .el-radio,
    .el-checkbox-group > .el-checkbox,
    .el-radio-group > label,
    .el-checkbox-group > label {
      position: relative !important;
      width: auto !important;
      height: auto !important;
      top: auto !important;
      left: auto !important;
      margin: 0 0 5px 0 !important;
      z-index: auto !important;
    }
    
    /* 单选框和多选框标签文本 */
    .el-radio__label, .el-checkbox__label {
      padding-left: 5px !important;
    }
    
    /* 特别处理直接作为label的情况 */
    label.el-radio, label.el-checkbox {
      position: relative !important;
      width: auto !important;
      height: auto !important;
      display: flex !important;
    }
  </style>
</head>
<body>
  <div id="app">
    <div class="container">
      <div class="header">
        <h2>${projectName || 'Easy Window 导出'}</h2>
      </div>
      <div class="empty-notice">
        <el-empty description="暂无组件数据" :image-size="200"></el-empty>
        <div class="help-text">
          <p>组件数据无法序列化或空白画布。</p>
          <p>请返回设计器添加组件或简化现有组件后重新导出。</p>
        </div>
        <div class="example-btn">
          <el-button type="primary">示例按钮</el-button>
          <el-button type="success">示例按钮</el-button>
        </div>
        <div class="checkbox-example">
          <el-checkbox-group>
            <el-checkbox label="选项1"></el-checkbox>
            <el-checkbox label="选项2"></el-checkbox>
          </el-checkbox-group>
        </div>
      </div>
    </div>
  </div>
  <script>
    const { createApp } = Vue;
    
    // 创建Miniblink通信桥
    window.miniBridge = {
      _eventHandlers: {},
      on(event, callback) { 
        if (!this._eventHandlers[event]) this._eventHandlers[event] = [];
        this._eventHandlers[event].push(callback);
        console.log('已注册事件监听:', event);
        return this;
      },
      emit(event, data) {
        console.log('触发事件:', event, data);
        if (window.external && window.external.notify) {
          try {
            window.external.notify(JSON.stringify({event, data}));
          } catch(e) {
            console.error('通知外部失败:', e);
          }
        }
        return this;
      }
    };
    
    window.MiniblinkCallback = function(msg) {
      try {
        const {event, data} = JSON.parse(msg);
        console.log('收到外部事件:', event, data);
        if (window.miniBridge._eventHandlers[event]) {
          window.miniBridge._eventHandlers[event].forEach(fn => fn(data));
        }
      } catch(e) { 
        console.error('MiniblinkCallback错误:', e); 
      }
    };
    
    // 应用程序
    const app = createApp({
      setup() {
        // 示例按钮的简单事件
        const handleClick = () => {
          alert('按钮点击事件');
          window.miniBridge.emit('button:click', { time: new Date().toISOString() });
        };
        
        // 修复复选框和单选框组的布局
        const fixCheckboxAndRadioLayout = () => {
          console.log('执行复选框和单选框布局修复...');
          // 修复复选框组
          document.querySelectorAll('.el-checkbox-group').forEach(group => {
            group.style.display = 'flex';
            group.style.flexDirection = 'column';
            group.style.alignItems = 'flex-start';
            group.style.gap = '10px';
            
            // 修复组内的复选框
            group.querySelectorAll('.el-checkbox').forEach(checkbox => {
              checkbox.style.position = 'relative';
              checkbox.style.width = 'auto';
              checkbox.style.height = 'auto';
              checkbox.style.margin = '0 0 5px 0';
              checkbox.style.display = 'flex';
              checkbox.style.alignItems = 'center';
              checkbox.style.left = 'auto';
              checkbox.style.top = 'auto';
              checkbox.style.zIndex = 'auto';
            });
          });
          
          // 修复单选框组
          document.querySelectorAll('.el-radio-group').forEach(group => {
            group.style.display = 'flex';
            group.style.flexDirection = 'column';
            group.style.alignItems = 'flex-start';
            group.style.gap = '10px';
            
            // 修复组内的单选框
            group.querySelectorAll('.el-radio').forEach(radio => {
              radio.style.position = 'relative';
              radio.style.width = 'auto';
              radio.style.height = 'auto';
              radio.style.margin = '0 0 5px 0';
              radio.style.display = 'flex';
              radio.style.alignItems = 'center';
              radio.style.left = 'auto';
              radio.style.top = 'auto';
              radio.style.zIndex = 'auto';
            });
          });
        };
        
        // 发送就绪信号
        setTimeout(() => {
          console.log('发送就绪信号');
          
          // 立即执行一次修复
          fixCheckboxAndRadioLayout();
          
          // 延迟执行几次，确保在DOM更新后还能正确修复
          setTimeout(fixCheckboxAndRadioLayout, 100);
          setTimeout(fixCheckboxAndRadioLayout, 500);
          
          window.miniBridge.emit('app:ready', { 
            components,
            canvasSize: {
              width: Number(canvasWidth) || 800,
              height: Number(canvasHeight) || 600
            }
          });
        }, 500);
        
        return {
          handleClick
        };
      }
    });
    
    app.use(ElementPlus);
    app.mount('#app');
  </script>
</body>
</html>`;
    }
    
    // 写入文件
    try {
      console.log('写入文件:', outputPath);
      fs.writeFileSync(outputPath, renderedHTML, 'utf-8');
      console.log('Miniblink导出成功:', outputPath);
      return { 
        success: true, 
        message: `Miniblink导出成功: ${outputPath}`, 
        filePath: outputPath 
      };
    } catch (writeErr) {
      console.error('写入文件失败:', writeErr);
      return { 
        success: false, 
        message: `写入文件失败: ${writeErr.message}. 请检查文件路径和权限。` 
      };
    }
  } catch (error) {
    console.error('处理Miniblink直接导出失败:', error);
    return { 
      success: false, 
      message: `导出失败: ${error.message}. 请尝试选择不同的保存位置或检查文件路径。` 
    };
  }
});

// 处理Miniblink空组件导出（极端情况下的回退方案）
ipcMain.handle('handle-miniblink-empty-export', async (event, basicData) => {
  try {
    const { 
      outputPath, 
      projectName, 
      canvasWidth, 
      canvasHeight,
      canvasBackgroundColor,  // 添加画布背景色
      canvasBorderWidth,      // 添加画布边框宽度
      canvasBorderStyle,      // 添加画布边框样式
      canvasBorderColor,      // 添加画布边框颜色
      canvasBorderRadius      // 添加画布边框圆角
    } = basicData;
    
    console.log('空导出路径:', outputPath);
    console.log('画布样式:', {
      背景色: canvasBackgroundColor || '#ffffff',
      边框宽度: canvasBorderWidth || '1px',
      边框样式: canvasBorderStyle || 'solid',
      边框颜色: canvasBorderColor || '#cccccc',
      边框圆角: canvasBorderRadius || '0px'
    });
    
    // 确保目录存在 - 使用更健壮的目录路径提取
    let dirPath;
    try {
      // 标准化路径 (统一使用正斜杠)
      const normalizedPath = outputPath.replace(/\\/g, '/');
      // 提取目录路径
      dirPath = path.dirname(normalizedPath);
      
      console.log('目标目录:', dirPath);
      
      // 检查目录是否存在，不存在则创建
      if (!fs.existsSync(dirPath)) {
        console.log('创建目录:', dirPath);
        // 使用recursive:true确保创建所有必要的父目录
        fs.mkdirSync(dirPath, { recursive: true });
      } else {
        console.log('目录已存在:', dirPath);
      }
    } catch (dirError) {
      console.error('目录处理出错:', dirError);
      return { 
        success: false, 
        message: `目录创建失败: ${dirError.message}. 请确保有权限创建此目录，或选择其他保存位置。` 
      };
    }
    
    // 构建简单HTML
    const simpleHTML = `<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>${projectName || 'Miniblink UI'}</title>
  <!-- Vue 3 -->
  <script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
  <!-- Element Plus -->
  <link rel="stylesheet" href="https://unpkg.com/element-plus/dist/index.css">
  <script src="https://unpkg.com/element-plus"></script>
  <style>
    body, html { 
      margin: 0; 
      padding: 0; 
      height: 100%; 
      font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", sans-serif; 
      display: flex;
      justify-content: center;
      align-items: center;
      background-color: #f5f7fa;
    }
    #app { 
      width: ${canvasWidth || 800}px; 
      height: ${canvasHeight || 600}px; 
      position: relative;
      margin: 0 auto;
      overflow: hidden;
      background-color: ${canvasBackgroundColor || '#ffffff'};
      border: ${canvasBorderWidth || 1}px ${canvasBorderStyle || 'solid'} ${canvasBorderColor || '#cccccc'};
      border-radius: ${canvasBorderRadius || 0}px;
      box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 12px;
      box-sizing: border-box;
    }
    
    /* 根元素样式 - 确保画布样式也应用到这里 */
    [data-component-id="root"] {
      width: 100% !important;
      height: 100% !important;
      position: relative !important;
      background-color: ${canvasBackgroundColor || '#ffffff'} !important;
      border-radius: ${canvasBorderRadius || 0}px !important;
      border: ${canvasBorderWidth || 1}px ${canvasBorderStyle || 'solid'} ${canvasBorderColor || '#cccccc'} !important;
      box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 12px !important;
      box-sizing: border-box !important;
      overflow: hidden !important;
    }
    
    /* 单选框和多选框样式修复 */
    .el-radio-group, .el-checkbox-group {
      display: flex !important;
      flex-direction: column !important;
      gap: 10px !important;
      align-items: flex-start !important;
    }
    
    .el-radio, .el-checkbox {
      margin-right: 0 !important;
      margin-bottom: 0 !important;
      width: auto !important;
      height: auto !important;
      position: relative !important;
      display: flex !important;
      align-items: center !important;
    }
  </style>
</head>
<body>
  <div id="app">
    <div style="text-align: center; padding: 20px;">
      <img src="https://element-plus.org/images/element-plus-logo.svg" style="width: 120px; margin-bottom: 20px;">
      <h2>${projectName || 'Easy Window 导出'}</h2>
      <p>这是一个空白的画布。您可以在此基础上开始构建界面。</p>
    </div>
  </div>
  
  <script>
    // 初始化Vue应用
    const app = Vue.createApp({
      data() {
        return {
          message: '欢迎使用 Easy Window 导出的UI！'
        }
      }
    });
    
    // 使用Element Plus
    app.use(ElementPlus);
    
    // 挂载应用
    app.mount('#app');
    
    // Miniblink交互API
    window.getComponentValue = function(id) {
      console.log('获取组件值:', id);
      return null; // 空画布没有组件
    };
    
    window.setComponentValue = function(id, value) {
      console.log('设置组件值:', id, value);
      return false; // 空画布没有组件
    };
    
    window.getComponentValues = function() {
      console.log('获取所有组件值');
      return {}; // 空画布没有组件
    };
    
    window.addEventListener('DOMContentLoaded', function() {
      // 页面就绪后通知
      console.log('页面已就绪');
      if (window.external && window.external.OnDocumentReady) {
        window.external.OnDocumentReady();
      }
    });
  </script>
</body>
</html>`;

    // 写入HTML文件
    try {
      fs.writeFileSync(outputPath, simpleHTML);
      return { success: true, message: '导出成功（空白画布）', filePath: outputPath };
    } catch (writeErr) {
      console.error('写入HTML文件失败:', writeErr);
      return { success: false, message: `保存失败: ${writeErr.message}` };
    }
  } catch (error) {
    console.error('空白导出出错:', error);
    return { success: false, message: `导出失败: ${error.message}` };
  }
});

// --- Handler for directly saving files with full path ---
ipcMain.handle('save-file-direct', async (event, { content, filePath }) => {
  try {
    console.log('直接保存文件:', filePath);
    
    if (!filePath) {
      return { success: false, message: '文件路径不能为空' };
    }
    
    // 确保目录存在
    const dirPath = path.dirname(filePath);
    console.log('确保目录存在:', dirPath);
    
    if (!fs.existsSync(dirPath)) {
      console.log('创建目录:', dirPath);
      fs.mkdirSync(dirPath, { recursive: true });
    }
    
    // 写入文件
    fs.writeFileSync(filePath, content, 'utf-8');
    console.log('文件写入成功');
    
    return {
      success: true,
      message: '文件保存成功',
      filePath
    };
  } catch (error) {
    console.error('直接保存文件失败:', error);
    return {
      success: false,
      message: `保存文件失败: ${error.message}`,
      error: error.message
    };
  }
});

// --- Handler for opening directories ---